package com.sinosoft.taxbenefit.core.policystatechange.biz.service.impl;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.sinosoft.platform.base.TaxBaseService;
import com.sinosoft.platform.common.config.SystemConstants;
import com.sinosoft.platform.common.exception.BusinessDataErrException;
import com.sinosoft.platform.common.util.DateUtil;
import com.sinosoft.platform.common.util.ReflectionUtil;
import com.sinosoft.platform.common.util.StringUtil;
import com.sinosoft.taxbenefit.api.base.HXResultCodeDTO;
import com.sinosoft.taxbenefit.api.config.ENUM_BZ_RESPONSE_RESULT;
import com.sinosoft.taxbenefit.api.config.ENUM_DISPOSE_TYPE;
import com.sinosoft.taxbenefit.api.config.ENUM_SENDSERVICE_CODE;
import com.sinosoft.taxbenefit.api.dto.request.TaxFaulTaskDTO;
import com.sinosoft.taxbenefit.api.dto.request.base.CoreRequestHead;
import com.sinosoft.taxbenefit.api.dto.request.base.ParamHeadDTO;
import com.sinosoft.taxbenefit.api.dto.request.base.ThirdSendResponseDTO;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolciyStateCoverage;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolicyStateEndorsement;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolicyStateInsured;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolicyStateLiability;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolicyStateMoreBody;
import com.sinosoft.taxbenefit.api.dto.request.policystate.PolicyStateOneBody;
import com.sinosoft.taxbenefit.api.dto.response.policystate.ResultEndorsement;
import com.sinosoft.taxbenefit.core.common.biz.service.CommonCodeService;
import com.sinosoft.taxbenefit.core.common.config.ENUM_BUSINESS_RESULR;
import com.sinosoft.taxbenefit.core.common.config.ENUM_EBAO_SERVICE_PORT_CODE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_HX_SERVICE_PORT_CODE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_RC_STATE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_RESULT_CODE;
import com.sinosoft.taxbenefit.core.common.config.ENUUM_CODE_MAPPING;
import com.sinosoft.taxbenefit.core.common.dto.BookSequenceDTO;
import com.sinosoft.taxbenefit.core.common.dto.EbaoServerPortDTO;
import com.sinosoft.taxbenefit.core.common.dto.ReqBusinessDTO;
import com.sinosoft.taxbenefit.core.common.dto.ReqBusinessDetailDTO;
import com.sinosoft.taxbenefit.core.common.dto.SendLogDTO;
import com.sinosoft.taxbenefit.core.common.dto.ThirdSendDTO;
import com.sinosoft.taxbenefit.core.ebaowebservice.AsynResultQueryService;
import com.sinosoft.taxbenefit.core.ebaowebservice.AsynResultQueryService_Service;
import com.sinosoft.taxbenefit.core.ebaowebservice.PolicyStatusChangeService;
import com.sinosoft.taxbenefit.core.ebaowebservice.PolicyStatusChangeService_Service;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseBody;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseHeader;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseJSON;
import com.sinosoft.taxbenefit.core.faultTask.biz.service.FaultTaskService;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxContMapper;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxContPolicyDutyMapper;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxContStateTrackMapper;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxFaultTaskMapper;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxPolicyRiskMapper;
import com.sinosoft.taxbenefit.core.generated.model.TaxCont;
import com.sinosoft.taxbenefit.core.generated.model.TaxContExample;
import com.sinosoft.taxbenefit.core.generated.model.TaxContPolicyDuty;
import com.sinosoft.taxbenefit.core.generated.model.TaxContPolicyDutyExample;
import com.sinosoft.taxbenefit.core.generated.model.TaxContStateTrack;
import com.sinosoft.taxbenefit.core.generated.model.TaxFaultTask;
import com.sinosoft.taxbenefit.core.generated.model.TaxPolicyRisk;
import com.sinosoft.taxbenefit.core.generated.model.TaxPolicyRiskExample;
import com.sinosoft.taxbenefit.core.policystatechange.biz.service.PolicyStateChangeService;
import com.sinosoft.taxbenefit.core.policystatechange.config.ENUM_POLICYSTATE_TYPE;
import com.sinosoft.taxbenefit.core.policystatechange.dto.EndorsementResult;
import com.sinosoft.taxbenefit.core.policystatechange.dto.EndorsementResultList;
import com.sinosoft.taxbenefit.core.policystatechange.dto.PolicyCoverage;
import com.sinosoft.taxbenefit.core.policystatechange.dto.PolicyEndorsement;
import com.sinosoft.taxbenefit.core.policystatechange.dto.PolicyEndorsementListBody;
import com.sinosoft.taxbenefit.core.policystatechange.dto.PolicyInsured;
import com.sinosoft.taxbenefit.core.policystatechange.dto.PolicyLiability;
import com.sinosoft.taxbenefit.core.transCode.biz.service.TransCodeService;

@Service
public class PolicyStateChangeServiceImpl extends TaxBaseService implements PolicyStateChangeService {
	@Autowired
	private TaxContStateTrackMapper contStateTrackMapper;
	@Autowired
	private FaultTaskService faultTaskService;
	@Autowired
	TaxFaultTaskMapper taxFaultTaskMapper;//异常任务
	@Autowired
	CommonCodeService commonCodeService;
	@Autowired
	private TaxContMapper taxContMapper;// 保单
	@Autowired
	private TaxPolicyRiskMapper taxPolicyRiskMapper;// 险种
	@Autowired
	private TaxContPolicyDutyMapper taxContPolicyDutyMapper;// 险种责任
	@Autowired
	TransCodeService transCodeService;// 转码

	@Override
	public ThirdSendResponseDTO modifyPolicyState(List<PolicyStateEndorsement> policybody, ParamHeadDTO paramHead) {
		String portCode = paramHead.getPortCode();
		String port = null;
		ThirdSendResponseDTO thirdSendResponse = new ThirdSendResponseDTO();
		try {
			List<ReqBusinessDetailDTO> reqBusinessDetailList = new ArrayList<ReqBusinessDetailDTO>();
			ReqBusinessDTO businessDTO = commonCodeService.initReqBusinessDTO();
			if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.code().equals(portCode)) {
				port = ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.desc();
			} else if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.code().equals(portCode)) {
				port = ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.desc();
			} else{
				port = "未区分请求编码";
			}
			logger.info(port + "保单状态修改（核心请求）JSON 体数据内容："+ JSONObject.toJSONString(policybody));
			// 封装成中保信dto
			List<PolicyEndorsement> endorsement = this.createDto(policybody);
			// 最外层｛｝
			PolicyEndorsementListBody endorsementList = new PolicyEndorsementListBody();
			endorsementList.setEndorsementList(endorsement);
			// 2.调用中保信接口服务,获得返回结果 存储调用中保信日志表
			ThirdSendDTO thirdSendDTO = commonCodeService.createThirdSend(ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code(),paramHead, endorsementList);
			logger.info(port + "保单状态修改（请求中报信） JSON数据内容："+ JSONObject.toJSONString(thirdSendDTO));
			Holder<ResponseHeader> responseHeaderHolder = new Holder<ResponseHeader>();
			Holder<ResponseBody> responseBodyHolder = new Holder<ResponseBody>();
			EbaoServerPortDTO ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code());
			String portUrl = ebaoServerPort.getPortUrl();
			URL wsdlLocation = new URL(portUrl);
			PolicyStatusChangeService_Service service = new PolicyStatusChangeService_Service(wsdlLocation);
			PolicyStatusChangeService servicePort = service.getPolicyStatusChangeServicePort();
			BindingProvider bp = (BindingProvider) servicePort;
			bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
			servicePort.statusChange(thirdSendDTO.getHead(), thirdSendDTO.getBody(), responseHeaderHolder,responseBodyHolder);
			ResponseHeader responseHeader = responseHeaderHolder.value;
			ResponseBody responseBody = responseBodyHolder.value;
			logger.info(port + "(中报信返回)JSON数据内容："+ responseBody.getJsonString());
			// 封装中保信返回报文
			ResponseJSON responseJSON = new ResponseJSON();
			responseJSON.setResponseBody(responseBody);
			responseJSON.setResponseHeader(responseHeader);
			// 封装发送报文日志对象
			SendLogDTO sendLog = new SendLogDTO();
			sendLog.setSerialNo(paramHead.getSerialNo());
			sendLog.setPortCode(ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code());
			sendLog.setRequestContent(JSONObject.toJSONString(thirdSendDTO));
			sendLog.setResponseContent(JSONObject.toJSONString(responseJSON));
			sendLog.setTargetCode(ENUM_SENDSERVICE_CODE.EBAO.code());
			sendLog.setState(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
			sendLog.setDescription(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			commonCodeService.addLogSend(sendLog);
			// 3.封装返回核心dto;
			// 中保信返回Dto(resultEndor)
			if (ENUM_RESULT_CODE.SUCCESS.code().equals(responseHeader.getResultCode())
					|| ENUM_RESULT_CODE.INPUT_LOCALITY_SUCCESS.code().equals(responseHeader.getResultCode())) {
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
				// 解析中保信返回结果
				EndorsementResultList resultEndorsement = JSONObject.parseObject(responseBody.getJsonString(),EndorsementResultList.class);
				List<EndorsementResult> resultlist = resultEndorsement.getEndorsementResultList();
				// 4.存储业务表数据
				modifyStateOfPolicy(policybody, resultlist);
			}else{
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
				List list = responseHeader.getResultMessage().getMessage();
				if(list != null && list.size() > 0){
					StringBuffer sbStr = new StringBuffer(); 
					for(String mess : responseHeader.getResultMessage().getMessage()){
						sbStr.append(mess).append("|");
					}
					String message = sbStr.substring(0, sbStr.length()-1).toString();
					thirdSendResponse.setResultDesc(message);
				}else{
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
				}
			}
			List<ResultEndorsement> endorsementResultList = new ArrayList<ResultEndorsement>();
			List<EndorsementResult> endorResult = null;
			boolean isRegisterFaulTask = false;
			if (!StringUtil.isEmpty(responseBody.getJsonString())) {
				// 解析中保信返回结果
				EndorsementResultList resultEndor = JSONObject.parseObject(responseBody.getJsonString(),EndorsementResultList.class);
				if (null != resultEndor.getEndorsementResultList()) {
					// 成功记录数
					Integer successNum = 0;
					// 失败记录数
					Integer failNum = 0;
					// 中保信Dto
					endorResult = resultEndor.getEndorsementResultList();
					for (PolicyStateEndorsement p : policybody) {
						// 循环中保信返回对象
						for (EndorsementResult r : endorResult) {
							if (r.getPolicyNo().equals(p.getPolicyNo())) {
								HXResultCodeDTO result = new HXResultCodeDTO();
								// 返回核心Dto
								ResultEndorsement endorsementResult = new ResultEndorsement();
								endorsementResult.setBizNo(p.getBizNo());
								endorsementResult.setEndorsementSequenceNo(r.getEndorsementSequenceNo());
								StringBuffer sb = new StringBuffer();
								result.setResultCode(r.getResult().getResultCode());
								String message = "";
								if (r.getResult().getResultMessage() != null) {
									for (String mess : r.getResult().getResultMessage()) {
										sb.append(mess).append("|");
									}
									message = sb.substring(0, sb.length() - 1).toString();
									result.setResultMessage(message);
								}
								endorsementResult.setResult(result);
								endorsementResultList.add(endorsementResult);
								// 成功记录计数
								if (ENUM_RESULT_CODE.SUCCESS.code().equals(r.getResult().getResultCode())) {
									successNum += 1;
								} else {
									// 失败记录计数
									failNum += 1;
									ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
									reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
									reqBusinessDetailDTO.setResultMessage(message);
									reqBusinessDetailList.add(reqBusinessDetailDTO);
								}
							}
						}
					}
					// 判断多笔还是单笔返回
					if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.code().equals(portCode)) {
						thirdSendResponse.setResJson(endorsementResultList.get(0));
					} else if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_MORE.code().equals(portCode)) {
						thirdSendResponse.setResJson(endorsementResultList);
					}
					// 登记请求记录
					businessDTO.setReqSuccessNum(successNum);
					businessDTO.setReqFailNum(failNum);
					isRegisterFaulTask = true;
				} else {
					BookSequenceDTO bookSequence = JSONObject.parseObject(responseBody.getJsonString(),BookSequenceDTO.class);
					// 插入异常任务表
					TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
					taxFaultTask.setSerialNo(paramHead.getSerialNo());
					taxFaultTask.setServerPortCode(paramHead.getPortCode());
					taxFaultTask.setServerPortName(paramHead.getPortName());
					taxFaultTask.setAreaCode(paramHead.getAreaCode());
					taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
					taxFaultTask.setBookSequenceNo(bookSequence.getBookingSequenceNo());
					faultTaskService.addTaxFaultTask(taxFaultTask);
					thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
				}
			} else {
				businessDTO.setReqFailNum(responseHeader.getRecordNum());
				for (int i = 0; i < responseHeader.getRecordNum(); i++) {
					ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
					reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
					reqBusinessDetailDTO.setResultMessage(thirdSendResponse.getResultDesc());
					reqBusinessDetailList.add(reqBusinessDetailDTO);
				}
			}
			if (isRegisterFaulTask) {
				// 添加记录失败明细
				commonCodeService.addReqBusinessDetail(reqBusinessDetailList);
				// 添加请求交易记录数
				businessDTO.setRequetNum(responseHeader.getRecordNum());
				commonCodeService.addReqBusinessCollate(businessDTO);
			}
		} catch (Exception e) {
			e.printStackTrace();
			thirdSendResponse.setResJson(e.getMessage());
			thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
			thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
			taxFaultTask.setServerPortCode(paramHead.getPortCode());
			taxFaultTask.setServerPortName(paramHead.getPortName());
			taxFaultTask.setAreaCode(paramHead.getAreaCode());
			taxFaultTask.setSerialNo(paramHead.getSerialNo());
			taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.ERROR.code());
			faultTaskService.addTaxFaultTask(taxFaultTask);
			logger.error(port + "后置处理失败：" + e.getMessage());
		}
		return thirdSendResponse;
	}
	/**
	 * 修改保单状态业务持久化
	 * 
	 * @param policybody
	 */
	private void modifyStateOfPolicy(List<PolicyStateEndorsement> policybody, List<EndorsementResult> endorResult) {
		try {
			for (int i = 0; i < policybody.size(); i++) {
				// 循环结果
				for (EndorsementResult r : endorResult) {
					// 判断保单号是否一致
					if (policybody.get(i).getPolicyNo().equals(r.getPolicyNo())) {
						// 判断成功的
						if (r.getResult().getResultCode().equals(ENUM_RESULT_CODE.SUCCESS.code())) {
							// 保单信息
							TaxCont taxcont = queryPolicyByPolicyNo(policybody.get(i).getPolicyNo());
							if (taxcont != null) {
								TaxContStateTrack policyState = new TaxContStateTrack();
								String policyUpdateType = policybody.get(i).getPolicyStatusUpdateType();
								if (policyUpdateType.equals(ENUM_POLICYSTATE_TYPE.POLICYSTATE_CHANGE.code())) {
									taxcont.setContState(policybody.get(i).getPolicyStatus());
									taxcont.setModifierId(SystemConstants.SYS_OPERATOR);
									taxcont.setModifyDate(DateUtil.getCurrentDate());
									modifyPolicy(taxcont);
								} else if (policyUpdateType.equals(ENUM_POLICYSTATE_TYPE.POLICY_RISK_STATE_CHANGE.code())) {
									// 险种代码
									String riskCode = policybody.get(i).getInsuredList().get(i).getCoverageList().get(i).getComCoverageCode();
									// 险种
									TaxPolicyRisk policyRisk = queryRiskInfo(riskCode, taxcont.getSid());
									String riskState = policybody.get(i).getInsuredList().get(i).getCoverageList().get(i).getCoverageStatus();
									policyRisk.setRiskState(riskState);
									policyRisk.setModifierId(SystemConstants.SYS_OPERATOR);
									policyRisk.setModifyDate(DateUtil.getCurrentDate());
									modifyCoverage(policyRisk);
									String dutyState = policybody.get(i).getInsuredList().get(i).getCoverageList().get(i).getLiabilityList().get(i).getLiabilityStatus();
									String dutyCode = policybody.get(i).getInsuredList().get(i).getCoverageList().get(i).getLiabilityList().get(i).getLiabilityCode();
									if (dutyState != null) {
										TaxContPolicyDuty dutyInfo = queryDutyInfo(dutyCode, policyRisk.getSid());
										dutyInfo.setDutyState(dutyState);
										dutyInfo.setCreatorId(SystemConstants.SYS_OPERATOR);
										dutyInfo.setCreateDate(DateUtil.getCurrentDate());
										modifyLiability(dutyInfo);
									}
								}
								policyState.setContId(taxcont.getSid());
								policyState.setContNo(policybody.get(i).getPolicyNo());
								policyState.setEventType(policyUpdateType);
								policyState.setEventDescription(policybody.get(i).getTerminationReason());
								policyState.setApplyDate(DateUtil.getCurrentDate());
								policyState.setValidDate(DateUtil.getCurrentDate());
								policyState.setRcState(ENUM_RC_STATE.EFFECTIVE.getCode());
								policyState.setCreatorId(SystemConstants.SYS_OPERATOR);
								policyState.setCreateDate(DateUtil.getCurrentDate());
								policyState.setModifierId(SystemConstants.SYS_OPERATOR);
								policyState.setModifyDate(DateUtil.getCurrentDate());
								addPolicyStateTrack(policyState);
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("保单状态修改持久化失败" + e.getMessage());
		}
	}

	/**
	 * 封装中保信dto集合
	 * @param policy
	 */
	private List<PolicyEndorsement> createDto(List<PolicyStateEndorsement> policy) {
		List<PolicyEndorsement> endorsementList = new ArrayList<PolicyEndorsement>();
		for (PolicyStateEndorsement policyState : policy) {
			endorsementList.add(this.createPolicyEndorsement(policyState));
		}
		return endorsementList;
	}

	/**
	 * 核心DTO转中保信DTO
	 * @param reqpPolicy
	 * @return
	 */
	private PolicyEndorsement createPolicyEndorsement(PolicyStateEndorsement reqpPolicy) {
		// 批单信息
		PolicyEndorsement policyEndorsement = new PolicyEndorsement();
		ReflectionUtil.copyProperties(reqpPolicy, policyEndorsement);
		// 保单状态转码
		policyEndorsement.setPolicyStatus(transCodeService.transCode(ENUUM_CODE_MAPPING.STATE.code(), reqpPolicy.getPolicyStatus()));
		// 保单终止原因
		policyEndorsement.setTerminationReason(transCodeService.transCode(ENUUM_CODE_MAPPING.TERMINATIONREASON.code(),reqpPolicy.getTerminationReason()));
		List<PolicyInsured> insuredList = new ArrayList<PolicyInsured>();
		if (this.checkList(reqpPolicy.getInsuredList())) {
			// 批单信息 -- 被保人
			for (PolicyStateInsured reqInsured : reqpPolicy.getInsuredList()) {
				PolicyInsured policyInsured = new PolicyInsured();
				ReflectionUtil.copyProperties(reqInsured, policyInsured);
				List<PolicyCoverage> polciyCoverageList = new ArrayList<PolicyCoverage>();
				if (this.checkList(reqInsured.getCoverageList())) {
					// 被保人信息 -- 险种信息
					for (PolciyStateCoverage reqCoverage : reqInsured.getCoverageList()) {
						PolicyCoverage polciyCoverage = new PolicyCoverage();
						ReflectionUtil.copyProperties(reqCoverage,polciyCoverage);
						// 主副险标记转码
						polciyCoverage.setCoverageType(transCodeService.transCode(ENUUM_CODE_MAPPING.MAINFLAG.code(),reqCoverage.getCoverageType()));
						// 险种状态转码
						polciyCoverage.setCoverageStatus(transCodeService.transCode(ENUUM_CODE_MAPPING.STATE.code(),reqCoverage.getCoverageStatus()));
						// 险种终止原因
						polciyCoverage.setTerminationReason(transCodeService.transCode(ENUUM_CODE_MAPPING.TERMINATIONREASON.code(), reqCoverage.getTerminationReason()));
						// 险种信息 -- 责任信息
						List<PolicyLiability> liabilityList = new ArrayList<PolicyLiability>();
						if (this.checkList(reqCoverage.getLiabilityList())) {
							// 循环责任
							for (PolicyStateLiability reqLiability : reqCoverage.getLiabilityList()) {
								PolicyLiability policyLiability = new PolicyLiability();
								ReflectionUtil.copyProperties(reqLiability,policyLiability);
								// 转码
								policyLiability.setLiabilityStatus(transCodeService.transCode(ENUUM_CODE_MAPPING.LIABILITYSTATUS.code(),reqLiability.getLiabilityStatus()));
								policyLiability.setLiabilityTermReason(transCodeService.transCode(ENUUM_CODE_MAPPING.TERMINATIONREASON.code(),reqLiability.getLiabilityTermReason()));
								liabilityList.add(policyLiability);
							}
						}
						polciyCoverage.setLiabilityList(liabilityList);
						polciyCoverageList.add(polciyCoverage);
					}
				}
				policyInsured.setCoverageList(polciyCoverageList);
				insuredList.add(policyInsured);
			}
		}
		policyEndorsement.setInsuredList(insuredList);
		return policyEndorsement;
	}

	private TaxCont queryPolicyByPolicyNo(String policyNO) {
		TaxContExample example = new TaxContExample();
		example.createCriteria().andContNoEqualTo(policyNO);
		List<TaxCont> taxcont = taxContMapper.selectByExample(example);
		if (taxcont.size() > 0) {
			return taxcont.get(0);
		} else {
			throw new BusinessDataErrException("保单信息不存在");
		}
	}

	private void modifyPolicy(TaxCont policy) {
		taxContMapper.updateByPrimaryKeySelective(policy);
	}

	/**
	 * 添加保单状态记录
	 * 
	 * @param policyState
	 */
	private void addPolicyStateTrack(TaxContStateTrack policyState) {
		contStateTrackMapper.insert(policyState);

	}

	/**
	 * 查询险种
	 * 
	 * @param riskCode
	 * @param policyId
	 * @return
	 */
	private TaxPolicyRisk queryRiskInfo(String riskCode, Integer policyId) {

		TaxPolicyRiskExample example = new TaxPolicyRiskExample();
		example.createCriteria().andRiskCodeEqualTo(riskCode).andContIdEqualTo(policyId);
		TaxPolicyRisk risk = taxPolicyRiskMapper.selectByExample(example).get(0);
		if (risk != null) {

			return risk;
		} else {
			throw new BusinessDataErrException("险种不存在");
		}
	}

	private void modifyCoverage(TaxPolicyRisk polciyRisk) {
		taxPolicyRiskMapper.updateByPrimaryKeySelective(polciyRisk);

	}

	/**
	 * 查找险种的责任
	 * 
	 * @param dutyCode
	 * @param riskId
	 * @return
	 */
	private TaxContPolicyDuty queryDutyInfo(String dutyCode, Integer riskId) {
		TaxContPolicyDutyExample example = new TaxContPolicyDutyExample();
		example.createCriteria().andDutyCodeEqualTo(dutyCode).andPolIdEqualTo(riskId);
		return taxContPolicyDutyMapper.selectByExample(example).get(0);

	}

	/**
	 * 更新险种
	 * 
	 * @param liability
	 */
	private void modifyLiability(TaxContPolicyDuty liability) {

		taxContPolicyDutyMapper.updateByPrimaryKeySelective(liability);
	}

	/**
	 * 判断list是否为空
	 * 
	 * @param list
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private boolean checkList(List list) {
		return list != null && list.size() > 0;
	}

	/**
	 * 保单状态修改异常接口
	 */
	@SuppressWarnings("unchecked")
	@Override
	public TaxFaultTask modifyPolicyStateExceptionJob(String reqJSON, String portCode, Integer faultTaskId) {
		String port = null;
		logger.info("进入保单状态修改异常任务服务");
		ThirdSendResponseDTO thirdSendResponse = new ThirdSendResponseDTO();
		TaxFaultTask faultTask = taxFaultTaskMapper.selectByPrimaryKey(faultTaskId);
		try {
			List<ReqBusinessDetailDTO> reqBusinessDetailList = new ArrayList<ReqBusinessDetailDTO>();
			ReqBusinessDTO businessDTO = commonCodeService.initReqBusinessDTO();
			List<PolicyStateEndorsement> policybody = null;
			ParamHeadDTO paramHead = new ParamHeadDTO();
			CoreRequestHead coreRequestHead = new CoreRequestHead();
			if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.code().equals(portCode)) {
				port = ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.desc();
				// 单个解析List<PolicyStateEndorsement>
				policybody = new ArrayList<PolicyStateEndorsement>();
				PolicyStateOneBody reqObject = JSONObject.parseObject(reqJSON,PolicyStateOneBody.class);
				PolicyStateEndorsement policyState = (PolicyStateEndorsement) reqObject.getBody();
				policybody.add(policyState);
				coreRequestHead = reqObject.getRequestHead();
			} else if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_MORE.code().equals(portCode)) {
				port = ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_MORE.desc();
				// 多个解析
				PolicyStateMoreBody reqObject = JSONObject.parseObject(reqJSON,PolicyStateMoreBody.class);
				policybody = (List<PolicyStateEndorsement>) reqObject.getBody();
				coreRequestHead = reqObject.getRequestHead();
			} else {
				throw new BusinessDataErrException("请求接口编码有误! 错误接口编码为："+ portCode);
			}
			logger.info(port + "（核心请求）JSON 体数据内容："+ JSONObject.toJSONString(policybody));
			// 2. 封装头部信息
			paramHead.setPortCode(portCode);
			paramHead.setAreaCode(coreRequestHead.getAreaCode());
			paramHead.setRecordNum(coreRequestHead.getRecordNum());
			paramHead.setSerialNo(coreRequestHead.getSerialNo());
			ThirdSendDTO thirdSendDTO = new ThirdSendDTO();
			EbaoServerPortDTO ebaoServerPort = null;
			Holder<ResponseHeader> responseHeaderHolder = new Holder<ResponseHeader>();
			Holder<ResponseBody> responseBodyHolder = new Holder<ResponseBody>();
			// 预约码处理方式
			if (ENUM_DISPOSE_TYPE.APPOINTMENT.code().equals(faultTask.getDisposeType())) {
				// 3. 封装请求中保信数据
				paramHead.setRecordNum("1"); //异步请求接口请求记录数为1
				BookSequenceDTO bookSequence = new BookSequenceDTO();
				bookSequence.setBookingSequenceNo(faultTask.getRemark());
				thirdSendDTO = commonCodeService.createThirdSend( ENUM_EBAO_SERVICE_PORT_CODE.GET_POLICY_STATE_DISPOSE_RESULT.code(), paramHead, bookSequence);
				ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ASYN_RESULT_QUERY.code());
				logger.info("预约码 - 保单状态修改上传（请求中保信）JSON 数据内容(预约码类型)：" + JSONObject.toJSONString(thirdSendDTO));
				String portUrl = ebaoServerPort.getPortUrl();
				URL wsdlLocation = new URL(portUrl);
				AsynResultQueryService_Service service = new AsynResultQueryService_Service(wsdlLocation);
				AsynResultQueryService servicePort = service.getAsynResultQueryServicePort();
				BindingProvider bp = (BindingProvider) servicePort;
				bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
				servicePort.asynResultQuery(thirdSendDTO.getHead(), thirdSendDTO.getBody(),responseHeaderHolder, responseBodyHolder);
				// 错误或异常处理方式
			} else if (ENUM_DISPOSE_TYPE.ASYNC.code().equals(faultTask.getDisposeType()) || ENUM_DISPOSE_TYPE.ERROR.code().equals(faultTask.getDisposeType())) {
				// 1 转换为中保信Dto
				List<PolicyEndorsement> endorsement = this.createDto(policybody);
				// 最外层｛｝
				PolicyEndorsementListBody endorsementList = new PolicyEndorsementListBody();
				endorsementList.setEndorsementList(endorsement);
				thirdSendDTO = commonCodeService.createThirdSend( ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code(), paramHead, endorsementList);
				// 保单信息上传地址
				ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code());
				logger.info("异常任务 - 保单状态修改上传（请求中保信）JSON 数据内容："+ JSONObject.toJSONString(thirdSendDTO));
				String portUrl = ebaoServerPort.getPortUrl();
				URL wsdlLocation = new URL(portUrl);
				PolicyStatusChangeService_Service service = new PolicyStatusChangeService_Service(wsdlLocation);
				PolicyStatusChangeService servicePort = service.getPolicyStatusChangeServicePort();
				BindingProvider bp = (BindingProvider) servicePort;
				bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
				servicePort.statusChange(thirdSendDTO.getHead(),thirdSendDTO.getBody(), responseHeaderHolder,responseBodyHolder);
				
			} else {
				throw new BusinessDataErrException("异常类型有误! 错误异常类型为："+ ENUM_DISPOSE_TYPE.getEnumValueByKey(faultTask.getDisposeType()));
			}
			ResponseHeader responseHeader = responseHeaderHolder.value;
			ResponseBody responseBody = responseBodyHolder.value;
			logger.info("异常任务-" + port + "(中报信返回)JSON数据内容："+ responseBody.getJsonString());
			// 封装中保信返回报文
			ResponseJSON responseJSON = new ResponseJSON();
			responseJSON.setResponseBody(responseBody);
			responseJSON.setResponseHeader(responseHeader);
			// 封装发送报文日志对象
			if (ENUM_DISPOSE_TYPE.ASYNC.code().equals(faultTask.getDisposeType())) {
				SendLogDTO sendLog = new SendLogDTO();
				sendLog.setSerialNo(paramHead.getSerialNo());
				sendLog.setPortCode(ENUM_EBAO_SERVICE_PORT_CODE.POLICY_STATE_CHANGE.code());
				sendLog.setRequestContent(JSONObject.toJSONString(thirdSendDTO));
				sendLog.setResponseContent(JSONObject.toJSONString(responseJSON));
				sendLog.setTargetCode(ENUM_SENDSERVICE_CODE.EBAO.code());
				sendLog.setState(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				sendLog.setDescription(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
				commonCodeService.addLogSend(sendLog);
			}
			// 3.封装返回核心dto;
			// 初始化头部错误信息
			String messageBody = ENUM_BZ_RESPONSE_RESULT.FAIL.description();
			// 中保信返回Dto(resultEndor)
			if (ENUM_RESULT_CODE.SUCCESS.code().equals(responseHeader.getResultCode())
					|| ENUM_RESULT_CODE.INPUT_LOCALITY_SUCCESS.code().equals(responseHeader.getResultCode())) {
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
				// 解析中保信返回结果
				EndorsementResultList resultEndorsement = JSONObject.parseObject(responseBody.getJsonString(),EndorsementResultList.class);
				List<EndorsementResult> resultlist = resultEndorsement.getEndorsementResultList();
				// 4.存储业务表数据
				modifyStateOfPolicy(policybody, resultlist);
			}else if(ENUM_RESULT_CODE.REQ_AWAIT.code().equals(responseHeader.getResultCode())){
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			}else{
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
				List list = responseHeader.getResultMessage().getMessage();
				if(list != null && list.size() > 0){
					StringBuffer sbStr = new StringBuffer(); 
					for(String mess : responseHeader.getResultMessage().getMessage()){
						sbStr.append(mess).append("|");
					}
					String message = messageBody = sbStr.substring(0, sbStr.length()-1).toString();
					thirdSendResponse.setResultDesc(message);
				}else{
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
				}
			}
			List<ResultEndorsement> endorsementResultList = new ArrayList<ResultEndorsement>();
			List<EndorsementResult> endorResult = null;
			boolean isRegisterFaulTask = false;
			if (!StringUtil.isEmpty(responseBody.getJsonString())) {
				// 解析中保信返回结果
				EndorsementResultList resultEndor = JSONObject.parseObject( responseBody.getJsonString(),EndorsementResultList.class);
				if (null != resultEndor.getEndorsementResultList()) {
					// 成功记录数
					Integer successNum = 0;
					// 失败记录数
					Integer failNum = 0;
					// 中保信Dto
					endorResult = resultEndor.getEndorsementResultList();
					for (PolicyStateEndorsement p : policybody) {
						// 循环中保信返回对象
						for (EndorsementResult r : endorResult) {
							if (r.getPolicyNo().equals(p.getPolicyNo())) {
								HXResultCodeDTO result = new HXResultCodeDTO();
								ResultEndorsement endorsementResult = new ResultEndorsement();
								endorsementResult.setBizNo(p.getBizNo());
								endorsementResult.setEndorsementSequenceNo(r.getEndorsementSequenceNo());
								StringBuffer sb = new StringBuffer();
								result.setResultCode(r.getResult().getResultCode());
								String message = "";
								if (r.getResult().getResultMessage() != null) {
									for (String mess : r.getResult().getResultMessage()) {
										sb.append(mess).append("|");
									}
									message = sb.substring(0, sb.length() - 1).toString();
									result.setResultMessage(message);
								}
								endorsementResult.setResult(result);
								endorsementResultList.add(endorsementResult);
								// 成功记录计数
								if (ENUM_RESULT_CODE.SUCCESS.code().equals(r.getResult().getResultCode())) {
									successNum += 1;
								} else {
									// 失败记录计数
									failNum += 1;
									// 记录失败明细
									ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
									reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
									reqBusinessDetailDTO.setResultMessage(message);
									reqBusinessDetailList.add(reqBusinessDetailDTO);
								}
							}
						}
					}
					// 判断多笔还是单笔返回
					if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_ONE.code().equals(portCode)) {
						thirdSendResponse.setResJson(endorsementResultList.get(0));
					}else if (ENUM_HX_SERVICE_PORT_CODE.POLICY_STATE_CHANGE_MORE.code().equals(portCode)) {
						thirdSendResponse.setResJson(endorsementResultList);
					}
					// 登记请求记录
					businessDTO.setReqSuccessNum(successNum);
					businessDTO.setReqFailNum(failNum);
					isRegisterFaulTask = true;
				}else{
					BookSequenceDTO bookSequence = JSONObject.parseObject(responseBody.getJsonString(),BookSequenceDTO.class);
					// 插入异常任务表
					faultTask.setRemark(bookSequence.getBookingSequenceNo());
					faultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
					thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
				}
			} else {
				thirdSendResponse.setResJson(messageBody);
				businessDTO.setReqFailNum(responseHeader.getRecordNum());
				// 记录失败明细
				for (int i = 0; i < responseHeader.getRecordNum(); i++) {
					ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
					reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
					reqBusinessDetailDTO.setResultMessage(thirdSendResponse.getResultDesc());
					reqBusinessDetailList.add(reqBusinessDetailDTO);
				}
			}
			if (isRegisterFaulTask) {
				// 添加记录失败明细
				commonCodeService.addReqBusinessDetail(reqBusinessDetailList);
				// 添加请求交易记录数
				businessDTO.setRequetNum(responseHeader.getRecordNum());
				commonCodeService.addReqBusinessCollate(businessDTO);
				faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
			}else{
				faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
			}
		} catch (Exception e) {
			logger.error("异常任务-" + port + "后置处理失败：" + e.getMessage());
			e.printStackTrace();
			thirdSendResponse.setResJson(e.getMessage());
			thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
			thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
			faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
			if(ENUM_DISPOSE_TYPE.APPOINTMENT.code().equals(faultTask.getDisposeType())){
				faultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
			}else{
				faultTask.setDisposeType(ENUM_DISPOSE_TYPE.ERROR.code());
			}
		} finally{
			faultTask.setSuccessMessage(JSONObject.toJSONString(thirdSendResponse));
			faultTask.setDisposeDate(DateUtil.getCurrentDate());
			taxFaultTaskMapper.updateByPrimaryKeySelective(faultTask);
		}
		logger.error(port + "异常任务处理结束!");
		return faultTask;
	}
}
